package cn.com.blueInfo.bpm.template.repository.impl;

import cn.com.blueInfo.bpm.common.entity.BaseEntity;
import cn.com.blueInfo.bpm.common.enums.BaseDeleted;
import cn.com.blueInfo.bpm.common.repository.BaseRepository;
import cn.com.blueInfo.bpm.template.entity.Process;
import cn.com.blueInfo.bpm.template.mapper.ProcessMapper;
import cn.com.blueInfo.bpm.template.repository.ProcessRepository;
import cn.com.blueInfo.bpm.template.request.ProcessDTO;
import cn.com.blueInfo.core.entity.CurrentLoginUserInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 流程静态模板定义表 数据服务实现类
 * @author suxch
 * @since 2025-09-01 19:30:44
 */
@Log4j2
@Service
public class ProcessRepositoryImpl
        extends ServiceImpl<ProcessMapper, Process>
        implements ProcessRepository, BaseRepository<Process, ProcessDTO.QueryDTO> {

    @Autowired
    private CurrentLoginUserInfo currentLoginUserInfo;

    /**
     * 提供获取 CurrentLoginUserInfo 的方法（由实现类提供，避免接口中注入）
     * @return CurrentLoginUserInfo
     */
    @Override
    public CurrentLoginUserInfo getCurrentLoginUserInfo() {
        return currentLoginUserInfo;
    }

    /**
     * 新增流程静态模板定义
     * @param process 流程静态模板定义参数
     */
    @Override
    public Integer createProcess(Process process) {
        return sqlExecuteResult(save(process));
    }

    /**
     * 批量新增流程静态模板定义
     * @param processList 流程静态模板定义参数列表
     */
    @Override
    public Integer batchCreateProcess(List<Process> processList) {
        return sqlExecuteResult(saveBatch(processList), processList.size());
    }

    /**
     * 删除流程静态模板定义
     * @param processId 流程静态模板定义ID
     */
    @Override
    public Integer deleteProcess(Long processId) {
        Process process = new Process();
        process.setId(processId);
        process.setDeleted(BaseDeleted.DELETED);
        return sqlExecuteResult(removeById(process));
    }

    /**
     * 批量删除流程静态模板定义
     * @param processIdList 流程静态模板定义ID列表
     */
    @Override
    public Integer batchDeleteProcess(List<Long> processIdList) {
        List<Process> processList = new ArrayList<>();
        for (Long processId : processIdList) {
            Process process = new Process();
            process.setId(processId);
            process.setDeleted(BaseDeleted.DELETED);
            processList.add(process);
        }
        return sqlExecuteResult(removeBatchByIds(processList), processList.size());
    }

    /**
     * 更新部分流程静态模板定义
     * @param process 流程静态模板定义参数
     */
    @Override
    public Integer updateProcessPartial(Process process) {
        validateUpdateId(process.getId());
        LambdaUpdateWrapper<Process> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Process::getId, process.getId());
        return sqlExecuteResult(update(updateWrapper));
    }

    /**
     * 更新全部流程静态模板定义
     * @param process 流程静态模板定义参数
     */
    @Override
    public Integer updateProcess(Process process) {
        validateUpdateId(process.getId());
        return sqlExecuteResult(updateById(process));
    }

    /**
     * 查询一条流程静态模板定义
     * @param processId 流程静态模板定义ID
     */
    @Override
    public Process getProcessById(Long processId) {
        LambdaQueryWrapper<Process> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Process::getId, processId);
        return getOne(queryWrapper);
    }

    /**
     * 分页查询流程静态模板定义
     * @param processQueryDTO 流程静态模板定义参数
     */
    @Override
    public Page<Process> getProcessPage(ProcessDTO.QueryDTO processQueryDTO) {
        Page<Process> processPage = new Page<>(
                processQueryDTO.getPage(), processQueryDTO.getSize());
        LambdaQueryWrapper<Process> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, processQueryDTO);

        BaseDeleted deleted = processQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeletePage(processPage, queryWrapper);
        } else {
            return page(processPage, queryWrapper);
        }
    }

    /**
     * 根据条件查询 流程静态模板定义 数量
     * @param processQueryDTO 流程静态模板定义参数
     */
    @Override
    public Long getProcessCount(ProcessDTO.QueryDTO processQueryDTO) {
        LambdaQueryWrapper<Process> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, processQueryDTO);

        BaseDeleted deleted = processQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeleteCount(queryWrapper);
        } else {
            return count(queryWrapper);
        }
    }

    /**
     * 根据条件查询 流程静态模板定义
     * @param processQueryDTO 流程静态模板定义参数
     */
    @Override
    public List<Process> getProcessList(ProcessDTO.QueryDTO processQueryDTO) {
        LambdaQueryWrapper<Process> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper(queryWrapper, processQueryDTO);

        BaseDeleted deleted = processQueryDTO.getDeleted();
        if (ObjectUtils.isNotEmpty(deleted) && deleted.equals(BaseDeleted.DELETED)) {
            return baseMapper.selectDeleteList(queryWrapper);
        } else {
            return list(queryWrapper);
        }
    }

    private void queryWrapper(LambdaQueryWrapper<Process> queryWrapper, ProcessDTO.QueryDTO processQueryDTO) {

        String templateCode = processQueryDTO.getTemplateCode();
        queryWrapper.eq(StringUtils.isNotBlank(templateCode), Process::getTemplateCode, templateCode);

        String templateName = processQueryDTO.getTemplateName();
        queryWrapper.eq(StringUtils.isNotBlank(templateName), Process::getTemplateName, templateName);

        String version = processQueryDTO.getVersion();
        queryWrapper.eq(StringUtils.isNotBlank(version), Process::getVersion, version);

        String description = processQueryDTO.getDescription();
        queryWrapper.eq(StringUtils.isNotBlank(description), Process::getDescription, description);

        Long formId = processQueryDTO.getFormId();
        queryWrapper.eq(ObjectUtils.isNotEmpty(formId), Process::getFormId, formId);

        String processLoadFunc = processQueryDTO.getProcessLoadFunc();
        queryWrapper.eq(StringUtils.isNotBlank(processLoadFunc), Process::getProcessLoadFunc, processLoadFunc);

        String submitFunc = processQueryDTO.getSubmitFunc();
        queryWrapper.eq(StringUtils.isNotBlank(submitFunc), Process::getSubmitFunc, submitFunc);

        addQueryWrapper(queryWrapper, processQueryDTO, getCommonColumn());

    }

    private Map<String, SFunction<Process, ?>> getCommonColumn() {
        return BaseEntity.getCommonColumn(
                Process::getOrderNumber,
                Process::getTenantId,
                Process::getApplicationId,
                Process::getStatus,
                Process::getDeleted,
                Process::getDeleteUserId,
                Process::getDeleteTime,
                Process::getRemark,
                Process::getCreateUserId,
                Process::getCreateTime,
                Process::getUpdateUserId,
                Process::getUpdateTime,
                Process::getExtend1,
                Process::getExtend2,
                Process::getExtend3);
    }

}
